/***************************************************************************
 *   Copyright (C) 2006 by Autostop team                                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "autopackets.h"




// ===========================================================================
//                                 GAutoPacket
// ===========================================================================


// --------------------- GAutoPacket::registerPackets() ----------------------
void GAutoPacket::registerPackets()
{
	GNetPacketFactory * pFactory = GNetPacketFactory::instance();

	pFactory->registerPacket( PACKET_PARAMS,
							  &(GAutoParams::createPacket)
							);
	pFactory->registerPacket( PACKET_UDP_HOST_INFO,
							  &(GUDPHostInfo::createPacket)
							);
	pFactory->registerPacket( PACKET_AREAS_CONFIG,
							  &(GAutoAreasConfig::createPacket)
							);
	pFactory->registerPacket( PACKET_MARKERS_IMAGE,
							  &(GAutoMarkersImage::createPacket)
							);
	pFactory->registerPacket( PACKET_ROI_IMAGE,
							  &(GAutoRoiImage::createPacket)
							);
	pFactory->registerPacket( PACKET_SHUTTER_IMAGE,
							  &(GAutoShutterImage::createPacket)
							);
	pFactory->registerPacket( PACKET_OBJECTS_COORDINATES,
							  &(GAutoObjectCoordinates::createPacket)
							);
	pFactory->registerPacket( PACKET_FRAME,
							  &(GAutoFrame::createPacket)
							);
	pFactory->registerPacket( PACKET_FULL_FRAME,
							 &(GAutoFullFrame::createPacket)
							);
	pFactory->registerPacket( PACKET_REQUEST,
							 &(GAutoRequest::createPacket)
							);
	pFactory->registerPacket( PACKET_REPLY_FRAME,
							 &(GAutoReplyFrame::createPacket)
							);
	pFactory->registerPacket( PACKET_REPLY_AREAS_CONFIG,
							 &(GAutoReplyAreasConfig::createPacket)
							);
	pFactory->registerPacket( PACKET_REPLY_CAMERA_CONFIG,
							 &(GAutoReplyCameraConfig::createPacket)
							);
	pFactory->registerPacket( PACKET_REPLY_PARAMS,
							 &(GAutoReplyParams::createPacket)
							);
	pFactory->registerPacket( PACKET_REPLY_EVENTS,
							  &(GAutoReplyEvents::createPacket)
							);
	pFactory->registerPacket( PACKET_EVENT_TRIGGER,
							 &(GAutoEventTrigger::createPacket)
							);
}
// ---------------------------------------------------------------------------


// -------------------------- GAutoPacket::header() --------------------------
/// Creates approproate header using packet type info
GHeader GAutoPacket::header() const
{
	GHeader header;
	header.setType( packetType() );

	return header;
}
// ---------------------------------------------------------------------------




// ===========================================================================
//                                 GAutoRequest
// ===========================================================================


// ------------------------- GAutoRequest ------------------------------------
/// Request packer constructor. Requires request type and unique id,
/// used to identify associate requestwith its answer
GAutoRequest::GAutoRequest( GAutoRequest::RequestType type, quint32 id )
{
	_requestType	= type;
	_requestId		= id;
}
// ---------------------------------------------------------------------------


// ------------------------- GAutoRequest::write -----------------------------
/// Serializes request into stream
void GAutoRequest::writeData( QDataStream & out ) const
{
	out << (quint16)_requestType;
	out << _requestId;
}
// ---------------------------------------------------------------------------


// ------------------------- GAutoRequest::read ------------------------------
/// Regenrates object from stream
void GAutoRequest::readData( QDataStream & in )
{
	quint16 type;
	in >> type;
	in >> _requestId;

	_requestType = (RequestType) type;
}
// ---------------------------------------------------------------------------




// ===========================================================================
//                             GAutoParams
// ===========================================================================


// ------------------------- GAutoParams::write ------------------------------
/// Serializes request into stream
void GAutoParams::writeData( QDataStream & out ) const
{
		// prepare data
	QByteArray paramsData;
	QTextStream str( &paramsData, QIODevice::WriteOnly );
	_params.writeToStream( str );

	out << paramsData;
// 	out << _params;
}
// ---------------------------------------------------------------------------


// ------------------------- GAutoParams::read -------------------------------
/// Regenrates object from stream
void GAutoParams::readData( QDataStream & in )
{
	QByteArray paramsData;
// 	in >> _params;
	in >> paramsData;
	QTextStream str( &paramsData, QIODevice::ReadOnly );
	_params.readFromStream( str );
}
// ---------------------------------------------------------------------------




// ===========================================================================
//                             GAutoReplyFrame
// ===========================================================================


// ------------------------- GAutoReplyFrame::write --------------------------
/// Serializes packet into stream
void GAutoReplyFrame::writeData( QDataStream & out ) const
{
	out << _requestId;
	out << _width;
	out << _height;
	out << _image;
	out << _timestamp;
}
// ---------------------------------------------------------------------------


// ------------------------- GAutoReplyFrame::read ---------------------------
/// Regenrates object from stream
void GAutoReplyFrame::readData( QDataStream & in )
{
	in >> _requestId;
	in >> _width;
	in >> _height;
	in >> _image;
	in >> _timestamp;
}
// ---------------------------------------------------------------------------




// ===========================================================================
//                              GAutoAreasConfig
// ===========================================================================


// ------------------------- GAutoAreasConfig::write -------------------------
/// Serializes packet into stream
void GAutoAreasConfig::writeData( QDataStream & out ) const
{
	out << _data;
}
// ---------------------------------------------------------------------------


// ------------------------- GAutoAreasConfig::read --------------------------
/// Regenrates object from stream
void GAutoAreasConfig::readData( QDataStream & in )
{
	in >> _data;
}
// ---------------------------------------------------------------------------




// ===========================================================================
//                          GAutoReplyAreasConfig
// ===========================================================================


// ----------------------- GAutoReplyAreasConfig::write ----------------------
/// Serializes packet into stream
void GAutoReplyAreasConfig::writeData( QDataStream & out ) const
{
	out << _requestId;
	out << _data;
}
// ---------------------------------------------------------------------------


// ----------------------- GAutoReplyAreasConfig::read -----------------------
/// Regenrates object from stream
void GAutoReplyAreasConfig::readData( QDataStream & in )
{
	in >> _requestId;
	in >> _data;
}
// ---------------------------------------------------------------------------




// ===========================================================================
//                           GAutoReplyCameraConfig
// ===========================================================================


// ------------------------- GAutoReplyCameraConfig::write -------------------
/// Serializes packet into stream
void GAutoReplyCameraConfig::writeData( QDataStream & out ) const
{
	out << _requestId;
	out << _data;
}
// ---------------------------------------------------------------------------


// ------------------------- GAutoReplyCameraConfig::read --------------------
/// Regenrates object from stream
void GAutoReplyCameraConfig::readData( QDataStream & in )
{
	in >> _requestId;
	in >> _data;
}
// ---------------------------------------------------------------------------




// ===========================================================================
//                             GAutoReplyParams
// ===========================================================================


// ------------------------- GAutoReplyParams::write -------------------------
/// Serializes request into stream
void GAutoReplyParams::writeData( QDataStream & out ) const
{
	out << _requestId;
		// prepare data
	QByteArray paramsData;
	QTextStream str( &paramsData, QIODevice::WriteOnly );
	_params.writeToStream( str );

	out << paramsData;
}
// ---------------------------------------------------------------------------


// ------------------------- GAutoReplyParams::read --------------------------
/// Regenrates object from stream
void GAutoReplyParams::readData( QDataStream & in )
{
	in >> _requestId;
	
	QByteArray paramsData;
	in >> paramsData;
	QTextStream str( &paramsData, QIODevice::ReadOnly );
	_params.readFromStream( str );
}
// ---------------------------------------------------------------------------




// ===========================================================================
//                             GAutoReplyEvents
// ===========================================================================


// ----------------------- GAutoReplyEvents::write() -------------------------
/// Serializes packet into stream
void GAutoReplyEvents::writeData( QDataStream & out ) const
{
	out << _requestId;
	
	quint32 size = _events.size();
	
		// write number of objects in list
	out << size;
		// write objects
	foreach( Event event, _events )
	{
		out << event.id;
		out << event.type;
		out << event.dateTime;
		out << event.message;
		out << event.firstImage;
		out << event.secondImage;
	}
}
// ---------------------------------------------------------------------------


// ----------------------- GAutoReplyEvents::read() --------------------------
/// Regenrates object from stream
void GAutoReplyEvents::readData( QDataStream & in )
{
	in >> _requestId;
	
	quint32 size = 0;
	
		// read number of objects in the list 
	in >> size;
	
		// read objects
	for( quint32 i = 0; i < size; i++ )
	{
		quint64    id;
		quint8     type;
		QDateTime  dateTime;
		QString    message;
		QByteArray firstImage;
		QByteArray secondImage;
		
			// read element
		in >> id;
		in >> type;
		in >> dateTime;
		in >> message;
		in >> firstImage;
		in >> secondImage;
		
		Event event;
		
		event.id = id;
		event.type = type;
		event.dateTime = dateTime;
		event.message = message;
		event.firstImage = firstImage;
		event.secondImage = secondImage;
		
		addEvent( event );
	}
}
// ---------------------------------------------------------------------------




// ===========================================================================
//                            GAutoMarkersImage
// ===========================================================================


// ------------------------- GAutoMarkersImage::write ------------------------
/// Serializes packet into stream
void GAutoMarkersImage::writeData( QDataStream & out ) const
{
	quint32 width = _markersImage->width;
	quint32 height = _markersImage->height;
	QByteArray data( width * height, 0 );
	
	int counter = 0;
	foreach_pixel( p, _markersImage )
	{
		data[ counter++ ] = *p;
	}
	
	out << width;
	out << height;
	out << data;
}
// ---------------------------------------------------------------------------


// ------------------------- GAutoMarkersImage::read -------------------------
/// Regenrates object from stream
void GAutoMarkersImage::readData( QDataStream & in )
{
	quint32 width = 0;
	quint32 height = 0;
	QByteArray data;
	
	in >> width;
	in >> height;
	in >> data;
	
		// extract data to markers image 
	_markersImage = create_image( width, height );
	int counter = 0;
	foreach_pixel( p, _markersImage )
	{
		*p = data[ counter++ ];
	}
}
// ---------------------------------------------------------------------------




// ===========================================================================
//                            GAutoRoiImage
// ===========================================================================


// ------------------------- GAutoRoiImage::write ----------------------------
/// Serializes packet into stream
void GAutoRoiImage::writeData( QDataStream & out ) const
{
	quint32 width = _roiImage->width;
	quint32 height = _roiImage->height;
	QByteArray data( width * height, 0 );
	
	int counter = 0;
	foreach_pixel( p, _roiImage )
	{
		data[ counter++ ] = *p;
	}
	
	out << width;
	out << height;
	out << data;
}
// ---------------------------------------------------------------------------


// ------------------------- GAutoRoiImage::read -----------------------------
/// Regenrates object from stream
void GAutoRoiImage::readData( QDataStream & in )
{
	quint32 width = 0;
	quint32 height = 0;
	QByteArray data;
	
	in >> width;
	in >> height;
	in >> data;
	
		// extract data to roi image 
	_roiImage = create_image( width, height );
	int counter = 0;
	foreach_pixel( p, _roiImage )
	{
		*p = data[ counter++ ];
	}
}
// ---------------------------------------------------------------------------




// ===========================================================================
//                            GAutoShutterImage
// ===========================================================================


// ------------------------- GAutoShutterImage::write -------------------------
/// Serializes packet into stream
void GAutoShutterImage::writeData( QDataStream & out ) const
{
	quint32 width = _shutterImage->width;
	quint32 height = _shutterImage->height;
	QByteArray data( width * height, 0 );
	
	int counter = 0;
	foreach_pixel( p, _shutterImage )
	{
		data[ counter++ ] = *p;
	}
	
	out << width;
	out << height;
	out << data;
}
// ---------------------------------------------------------------------------


// ------------------------- GAutoShutterImage::read -------------------------
/// Regenrates object from stream
void GAutoShutterImage::readData( QDataStream & in )
{
	quint32 width = 0;
	quint32 height = 0;
	QByteArray data;
	
	in >> width;
	in >> height;
	in >> data;
	
		// extract data to shutter image 
	_shutterImage = create_image( width, height );
	int counter = 0;
	foreach_pixel( p, _shutterImage )
	{
		 *p = data[ counter++ ];
	}
}
// ---------------------------------------------------------------------------




// ===========================================================================
//                            GAutoObjectCoordinates
// ===========================================================================


// ----------------------- GAutoObjectCoordinates::write() -------------------
/// Serializes packet into stream
void GAutoObjectCoordinates::writeData( QDataStream & out ) const
{
	qint32 size = _objectsCoordinates.size();
	
		// write number of objects in list
	out << size;
		// write objects
	foreach( objectCoordinates object, _objectsCoordinates )
	{
		out << object.positionRect;
		out << object.barycentrumPoint;
		out << object.description;
		out << object.trace;
	}
}
// ---------------------------------------------------------------------------


// ----------------------- GAutoObjectCoordinates::read() --------------------
/// Regenrates object from stream
void GAutoObjectCoordinates::readData( QDataStream & in )
{
	qint32 size = 0;
	
		// read number of objects in the list 
	in >> size;
	
		// read objects
	for( int i = 0; i < size; i++ )
	{
		QRect          positionRect;
		QPoint         barycentrumPoint;
		QString         description;
		QList< QPair< QPoint, qint16 > > trace;
		
			// read element
		in >> positionRect;
		in >> barycentrumPoint;
		in >> description;
		in >> trace;
		
		append( positionRect, barycentrumPoint, description, trace );
	}
}
// ---------------------------------------------------------------------------




// ===========================================================================
//                                  GAutoFrame
// ===========================================================================


// ------------------------------ GAutoFrame::write() ------------------------
/// Serializes packet into stream
void GAutoFrame::writeData( QDataStream & out ) const
{
	out << (quint16)_type;
	out << _width;
	out << _height;
	out << _id;
	out << _image;
}
// ---------------------------------------------------------------------------


// ------------------------------- GAutoFrame::read() ------------------------
/// Regenrates object from stream
void GAutoFrame::readData( QDataStream & in )
{
	quint16 type;
	
	in >> type;
	_type = (ImageType)type;
	in >> _width;
	in >> _height;
	in >> _id;
	in >> _image;
}
// ---------------------------------------------------------------------------





// ===========================================================================
//                                GUDPHostInfo
// ===========================================================================


// -------------------- GUDPHostInfo::GUDPHostInfo() -------------------------
GUDPHostInfo::GUDPHostInfo( const QHostAddress hostAddress,
							quint16 port
						  )
	: GAutoPacket(), _hostAddress( hostAddress ) , _port( port )
{
	// nothing more
}
// ---------------------------------------------------------------------------


// ------------------- GUDPHostInfo::GUDPHostInfo() --------------------------
GUDPHostInfo::GUDPHostInfo()
	: GAutoPacket()
{
	// nothing
}
// ---------------------------------------------------------------------------


// --------------------- GUDPHostInfo::writeData() ---------------------------
void GUDPHostInfo::writeData( QDataStream & out ) const
{
	out << _hostAddress;
	out << _port;
}
// ---------------------------------------------------------------------------


// --------------------- GUDPHostInfo::readData() ----------------------------
void GUDPHostInfo::readData( QDataStream & in )
{
	in >> _hostAddress;
	in >> _port;
}
// ---------------------------------------------------------------------------




// ===========================================================================
//                                 GAutoEventTrigger
// ===========================================================================


// ------------------------- GAutoEventTrigger::write() ----------------------
/// Serializes event into stream
void GAutoEventTrigger::writeData( QDataStream & out ) const
{
	out << (quint16)_eventType;
	out << _message;
	out << _shutterTime;
	out << _sendTime;
}
// ---------------------------------------------------------------------------


// ------------------------- GAutoEventTrigger::read() -----------------------
/// Regenrates object from stream
void GAutoEventTrigger::readData( QDataStream & in )
{
	quint16 eventType;
	in >> eventType;
	in >> _message;
	in >> _shutterTime;
	in >> _sendTime;
	
	_eventType = (EventType) eventType;
	
}
// ---------------------------------------------------------------------------





// eof
